package routers

import (
	"bytes"
	"encoding/json"
	"net/http"
	"reflect"
	"strconv"

	"shqsoft.cn/pas3ui/base"
	"shqsoft.cn/pas3ui/popedom"
	"shqsoft.cn/pas3ui/reports"

	//log "github.com/cihub/seelog"
	"github.com/dgrijalva/jwt-go"
	"github.com/labstack/echo"
)

// FindRouter 路由：根据给定的WhereCause获取列表数据
func FindRouter(c echo.Context) error {
	daoName := c.Param("DaoName")
	if daoName == "" {
		return echo.NewHTTPError(http.StatusBadRequest, "daoName不能为空！")
	}
	pageNumberStr := c.Param("PageNumber")
	if pageNumberStr == "" {
		return echo.NewHTTPError(http.StatusBadRequest, "pageNumber不能为空！")
	}
	pageCountStr := c.Param("PageCount")
	if pageCountStr == "" {
		return echo.NewHTTPError(http.StatusBadRequest, "pageCount不能为空！")
	}
	permIDStr := c.FormValue("PermID")
	if permIDStr == "" || permIDStr == "undefined" || permIDStr == "null" {
		permIDStr = "0"
	}
	permID, err := strconv.Atoi(permIDStr)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, "PermID必须为整数！")
	}
	var whereCauses []base.WhereCause
	jsonStr := c.FormValue("WhereCauses")
	if jsonStr != "" {
		err := json.Unmarshal([]byte(jsonStr), &whereCauses)
		if err != nil {
			return echo.NewHTTPError(http.StatusBadRequest, err.Error())
		}
	}
	var orderItems []base.OrderItem
	jsonStr = c.FormValue("OrderItems")
	if jsonStr != "" {
		err := json.Unmarshal([]byte(jsonStr), &orderItems)
		if err != nil {
			return echo.NewHTTPError(http.StatusBadRequest, err.Error())
		}
	}
	if daoName == "DGCK_RD" {
		var orderItems2 []base.OrderItem
		orderItems2 = append(orderItems2, base.OrderItem{
			FieldName: "FPNO",
			Direction: "ASC",
		})
		orderItems2 = append(orderItems2, orderItems...)
		orderItems = orderItems2
	}
	if daoName == "PerfAssePara" {
		var orderItems2 []base.OrderItem
		orderItems2 = append(orderItems2, base.OrderItem{
			FieldName: "PANO",
			Direction: "ASC",
		})
		orderItems2 = append(orderItems, orderItems2...)
		orderItems = orderItems2
	}
	dao, err := base.GetDao(daoName)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	pageNumber, err := strconv.Atoi(pageNumberStr)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, "pageNumber必须为数字")
	}
	pageCount, err := strconv.Atoi(pageCountStr)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, "pageCount必须为数字")
	}
	user := c.Get("user").(*jwt.Token)
	claims := user.Claims.(*UserLoginClaims)
	pTypes, err := popedom.GetUserPermissionTypes(claims.UserID, permID)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	listData, err := dao.Find(whereCauses, orderItems, pageNumber, pageCount, claims.UserID, pTypes...)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	return c.JSON(http.StatusOK, listData)
}

func FindTableRouter(c echo.Context) error {
	tableName := c.Param("TableName")
	if tableName == "" {
		return echo.NewHTTPError(http.StatusBadRequest, "tableName不能为空！")
	}
	var fetch reports.Fetch
	valueTpl := c.FormValue("ValueTpl")
	if valueTpl == "" {
		return echo.NewHTTPError(http.StatusBadRequest, "valueTpl不能为空！")
	}
	optionTpl := c.FormValue("OptionTpl")
	if optionTpl == "" {
		return echo.NewHTTPError(http.StatusBadRequest, "optionTpl不能为空！")
	}
	value := c.FormValue("value")
	jsonStr := c.FormValue("SearchColumns")
	if jsonStr != "" {
		err := json.Unmarshal([]byte(jsonStr), &fetch.SearchColumns)
		if err != nil {
			return echo.NewHTTPError(http.StatusBadRequest, err.Error())
		}
	}
	isValSearch := false
	if len(fetch.SearchColumns) == 1 && fetch.SearchColumns[0] == valueTpl {
		isValSearch = true
	}
	var selectBuffer bytes.Buffer
	selectBuffer.WriteString("SELECT ")
	selectBuffer.WriteString(valueTpl + "," + optionTpl)
	selectBuffer.WriteString(" FROM ")
	selectBuffer.WriteString(tableName)
	if value != "undefined" {
		if len(fetch.SearchColumns) > 0 {
			selectBuffer.WriteString(" WHERE ")
			for _, search := range fetch.SearchColumns {
				if isValSearch {
					selectBuffer.WriteString(search + "='" + value + "'")
				} else {
					selectBuffer.WriteString(search + " LIKE '%" + value + "%'")
				}
				selectBuffer.WriteString(" OR ")
			}
			selectBuffer.Truncate(selectBuffer.Len() - 3)
		}
	}
	selectBuffer.WriteString(" LIMIT 10")
	sql := selectBuffer.String()
	rows, err := base.MYDB.Raw(sql).Rows()
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	dataMaps := make([]map[string]string, 0, 10)
	for rows.Next() {
		var vTpl, oTpl string
		rows.Scan(&vTpl, &oTpl)
		dMap := map[string]string{
			valueTpl:  vTpl,
			optionTpl: oTpl,
		}
		dataMaps = append(dataMaps, dMap)
	}
	rows.Close()
	return c.JSON(http.StatusOK, dataMaps)
}

// FindAllRouter 查询指定表的所有数据
func FindAllRouter(c echo.Context) error {
	daoName := c.Param("DaoName")
	if daoName == "" {
		return echo.NewHTTPError(http.StatusBadRequest, "daoName不能为空！")
	}
	var orderItems []base.OrderItem
	jsonStr := c.FormValue("OrderItems")
	if jsonStr != "" {
		err := json.Unmarshal([]byte(jsonStr), &orderItems)
		if err != nil {
			return echo.NewHTTPError(http.StatusBadRequest, err.Error())
		}
	}
	dao, err := base.GetDao(daoName)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	where := c.FormValue("where")
	listData, err := dao.FindAll(orderItems, where)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	return c.JSON(http.StatusOK, listData)
}

// AddRouter 路由：按照给定的实体类添加数据
func AddRouter(c echo.Context) error {
	dao, entity, err := getDaoAndEntity(c)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	pks, err := dao.Add(entity)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	return c.JSON(http.StatusOK, pks)
}

// DeleteRouter 路由：按照给定的实体类删除数据
func DeleteRouter(c echo.Context) error {
	dao, entity, err := getDaoAndEntity(c)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	count, err := dao.Delete(entity)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	return c.JSON(http.StatusOK, count)
}

// DeletesRouter 路由：按照给定的主键值（[]interface{}）删除数据
func DeletesRouter(c echo.Context) error {
	var pkVal []int
	jsonStr := c.FormValue("PrimaryKeyValues")
	err := json.Unmarshal([]byte(jsonStr), &pkVal)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	daoName := c.Param("DaoName")
	if daoName == "" {
		return echo.NewHTTPError(http.StatusBadRequest, "daoName不能为空！")
	}
	dao, err := base.GetDao(daoName)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	pkValObjs := make([]interface{}, len(pkVal))
	for i, v := range pkVal {
		pkValObjs[i] = v
	}
	count, err := dao.Deletes(pkValObjs...)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	return c.JSON(http.StatusOK, count)
}

// SaveDatasRouter 路由：批量保存数据
func SaveDatasRouter(c echo.Context) error {
	daoName := c.Param("DaoName")
	if daoName == "" {
		return echo.NewHTTPError(http.StatusBadRequest, "daoName不能为空！")
	}
	dao, err := base.GetDao(daoName)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	newDatas := dao.GetEntitis()
	jsonStr := c.FormValue("NewDatas")
	if jsonStr != "" {
		err = json.Unmarshal([]byte(jsonStr), newDatas)
	}
	updateDatas := dao.GetEntitis()
	jsonStr = c.FormValue("UpdateDatas")
	if jsonStr != "" {
		err = json.Unmarshal([]byte(jsonStr), updateDatas)
	}
	deleteDatas := dao.GetEntitis()
	jsonStr = c.FormValue("DeleteDatas")
	if jsonStr != "" {
		err = json.Unmarshal([]byte(jsonStr), deleteDatas)
	}
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	tx := base.MYDB.Begin()
	deleteDataArr := reflect.ValueOf(deleteDatas)
	l := deleteDataArr.Elem().Len()
	for i := 0; i < l; i++ {
		deleteData := deleteDataArr.Elem().Index(i).Addr().Interface()
		_, err = dao.Delete(deleteData)
		if err != nil {
			tx.Rollback()
			return echo.NewHTTPError(http.StatusBadRequest, err.Error())
		}
	}
	newDataArr := reflect.ValueOf(newDatas)
	l = newDataArr.Elem().Len()
	keysMap := make([]map[string]interface{}, l)
	for i := 0; i < l; i++ {
		newData := newDataArr.Elem().Index(i).Addr().Interface()
		keys, err := dao.Add(newData)
		if err != nil {
			tx.Rollback()
			return echo.NewHTTPError(http.StatusBadRequest, err.Error())
		}
		keysMap[i] = keys
	}
	updateDataArr := reflect.ValueOf(updateDatas)
	l = updateDataArr.Elem().Len()
	for i := 0; i < l; i++ {
		updateData := updateDataArr.Elem().Index(i).Addr().Interface()
		_, err = dao.Update(updateData)
		if err != nil {
			tx.Rollback()
			return echo.NewHTTPError(http.StatusBadRequest, err.Error())
		}
	}
	tx.Commit()
	return c.JSON(http.StatusOK, keysMap)
}

// UpdateRouter 路由：更新数据
func UpdateRouter(c echo.Context) error {
	dao, entity, err := getDaoAndEntity(c)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	count, err := dao.Update(entity)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	return c.JSON(http.StatusOK, count)
}

// BigTabColPieItemsRouter 路由：获取宽表字段的饼图项目
func BigTabColPieItemsRouter(c echo.Context) error {
	pieItems := base.GetBigTabColPieItems()
	return c.JSON(http.StatusOK, pieItems)
}
func getDaoAndEntity(c echo.Context) (base.Dao, interface{}, error) {
	daoName := c.Param("DaoName")
	if daoName == "" {
		return nil, nil, echo.NewHTTPError(http.StatusBadRequest, "daoName不能为空！")
	}
	if daoName == "BasePara2021" {
		daoName = "AssessMent"
	}
	dao, err := base.GetDao(daoName)
	if err != nil {
		return nil, nil, echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	entity := dao.GetEntity()
	jsonStr := c.FormValue("Entity")
	if jsonStr == "" {
		return nil, nil, echo.NewHTTPError(http.StatusBadRequest, "Entity不能为空！")
	}
	err = json.Unmarshal([]byte(jsonStr), entity)
	if err != nil {
		return nil, nil, echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	return dao, entity, nil
}
